﻿namespace ScrumLite.WebUx.Tests
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using ScrumLite.Services;
    using ScrumLite.Services.Contracts;
    using System.Globalization;

    public class MockDefectsService : IDefectsService
    {
        public bool AddDefectsCalled { get; set; }
        public bool GetDefectsCalled { get; set; }
        public string ProjectId { get; set; }
        public Defect DefectAdded { get; set; }

        private static List<Defect> defects;

        public const string ProjectIdForEmptyData = "D460E055-ED9D-4772-9230-63C9D15E6574";

        public MockDefectsService()
        {
            defects = Initialize();
        }

        private static List<Defect> Initialize()
        {
            List<Defect> defects = new List<Defect>();
            defects.Add(new Defect() 
            { 
                Id = Guid.NewGuid(), 
                Moniker = 1, 
                Notes = "Notes for the request", 
                Title = "Defect 1", 
                Decision = null, 
                CreatedBy = "User one", 
                CreatedOn = DateTime.Now, 
                Severity = 1, 
                TriagedOn = null, 
                DeliverableId = new Guid("A06A8A24-7DAF-408A-A0B1-3D63E5D42F29"), 
                Triaged = false, DaysOpen = 0 
            });

            defects.Add(new Defect() 
            { 
                Id = Guid.NewGuid(), 
                Moniker = 2, 
                Notes = "* Note 1 Note 1 Note 1 Note 1 Note 1 Note 1\r\n* Note 2 Note 2 Note 2 Note 2 Note 2 Note 2", 
                Title = "Defect 2", 
                Decision = "Decision Taken 1 Decision Taken 1 ", 
                CreatedBy = "User one", 
                CreatedOn = DateTime.Now.AddDays(-5), 
                Severity = 1, 
                TriagedOn = DateTime.Now, 
                DeliverableId = new Guid("A06A8A24-7DAF-408A-A0B1-3D63E5D42F29"), 
                Triaged = true, 
                DaysOpen = 15 
            });

            defects.Add(new Defect() 
            { 
                Id = Guid.NewGuid(),
                Moniker = 3, 
                Notes = null, 
                Title = "Defect 3", 
                Decision = null, 
                CreatedBy = "User one", 
                CreatedOn = DateTime.Now.AddDays(-21), 
                Severity = 1, 
                TriagedOn = null, 
                DeliverableId = new Guid("B06A8A24-7DAF-408A-A0B1-3D63E5D42F29"), 
                Triaged = false, 
                DaysOpen = 0 
            });

            defects.Add(new Defect() 
            {
                Id = Guid.NewGuid(),
                Moniker = 4, 
                Notes = null, 
                Title = "Defect 4", 
                Decision = "Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 Decision Taken 1 ", 
                CreatedBy = "User one",
                CreatedOn = DateTime.Now, 
                Severity = 1, 
                TriagedOn = DateTime.Now,
                DeliverableId = new Guid("C06A8A24-7DAF-408A-A0B1-3D63E5D42F29"),
                Triaged = true, DaysOpen = 33 });
            
            defects.Add(new Defect() 
            { 
                Id = Guid.NewGuid(), 
                Moniker = 5, 
                Notes = "Some notes here", 
                Title = "Defect 5", 
                Decision = "Action Taken 5", 
                CreatedBy = "User one",
                CreatedOn = DateTime.Now.AddDays(-10), 
                Severity = 1, 
                TriagedOn = DateTime.Now, 
                DeliverableId = new Guid("B06A8A24-7DAF-408A-A0B1-3D63E5D42F29"), 
                Triaged = true, 
                DaysOpen = 10 
            });

            return defects;
        }

        public Collection<Defect> GetDefects(string projectId, byte triaged)
        {
            if (projectId != ProjectIdForEmptyData)
            {
                this.ProjectId = projectId;
                this.GetDefectsCalled = true;
                return new Collection<Defect>(defects);
            }
            else
            {
                return new Collection<Defect>();
            }
        }

        public Defect GetDefect(string projectId, int moniker)
        {
            var defect = (from d in defects 
                         where d.Moniker == moniker
                              select d).SingleOrDefault();

            return defect;
        }


        public void AddDefect(Defect defect)
        {
            defects.Add(defect);
            DefectAdded = defect;
            AddDefectsCalled = true;
        }

        public void UpdateDefect(Defect defect)
        {
            Defect oldDefect = defects.Where(d => d.Id == defect.Id).SingleOrDefault();
            
            oldDefect.Title = defect.Title;
            oldDefect.Decision = defect.Decision;
            oldDefect.CreatedBy = defect.CreatedBy;
            oldDefect.CreatedOn = defect.CreatedOn;
            oldDefect.DaysOpen = defect.DaysOpen;
            oldDefect.CreatedBy = defect.CreatedBy;
            oldDefect.Notes = defect.Notes;
            oldDefect.Severity = defect.Severity;
            oldDefect.Triaged = defect.Triaged;
            oldDefect.TriagedOn = defect.TriagedOn;
            oldDefect.DeliverableId = defect.DeliverableId;
        }

        public int GetNextMoniker(string projectId)
        {
            var currentMoniker = (from d in defects
                                  select d.Moniker).Max();
            return ++currentMoniker;
        }

        public void DeleteDefect(Guid defectId)
        {
            var defect = (from d in defects
                          where d.Id == defectId
                          select d).SingleOrDefault();

            defects.Remove(defect);
        }

        public void SaveDefects(Defect[] defects)
        {
            foreach (Defect defect in defects)
            {
                this.UpdateDefect(defect);
            }
        }

        #region IDefectsService Members


        public Defect[] GetDefectsByDeliverable(string projectId, string deliverableId)
        {
            Defect[] filtredDefects = (from d in defects
                                      where d.DeliverableId.ToString().ToLower(CultureInfo.CurrentCulture).Equals(deliverableId.ToLower(CultureInfo.CurrentCulture))
                                      select d).ToArray();

            return filtredDefects;
        }

        #endregion
    }
}
